package com.ji.server;

import com.ji.AbstractPeer;
import com.ji.NioSession;
import com.ji.SessionManager;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.util.Iterator;

/**
 * Title:
 * Description:
 * Author:吉
 * Since:2017/5/19
 * Version:1.1.0
 */
public class EchoServer implements AbstractPeer, Runnable {

    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;

    @Override
    public void open() {
        int threadNum = Runtime.getRuntime().availableProcessors() + 1;
        bossGroup = new NioEventLoopGroup(threadNum, new NamedThreadFactory("NettyServerBoss", true));
        workerGroup = new NioEventLoopGroup(threadNum, new NamedThreadFactory("NettyServerWorker", true));
        ServerBootstrap bootstrap = new ServerBootstrap();// 引导辅助程序
        bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 100)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
//                        p.addLast(new LoggingHandler(LogLevel.INFO));
                        p.addLast(
//                                new ObjectEncoder(),
//                                new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
                                new ProtocolEncoder(),
                                new ProtocolDecoder(),
                                new EchoServerHandler());
                    }
                });
        // Start the server.
        ChannelFuture f;
        try {
            f = bootstrap.bind("127.0.0.1", 8007).sync();
            // Wait until the server socket is closed.
            f.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("closed");
    }

    @Override
    public void close() {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }

    @Override
    public void run() {
        open();
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new EchoServer());

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    Iterator<NioSession> iterator = SessionManager.getAllSession().iterator();
                    while (iterator.hasNext()) {
                        NioSession session = iterator.next();
                        session.write("这是广播,你的sessionID是"+session.getSessionId());
                    }
                    try {
                        Thread.sleep(1000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t.start();
        t2.start();
        Thread.currentThread().join();
    }
}
